/**
 ******************************************************************************
 * @file           : lmx2572.c
 * @brief          : PLL 生成2.4G 等的射频时钟
 * @author         : L0061 -liuzhiping 542431620@qq.com
 ******************************************************************************
 * @attention
 *  Copyright (c) 2021  awptech.co.ltd.
 * All rights reserved.
 ******************************************************************************
 */
#include "lmx2572.h"
#include "elog.h"

#define LOG_TAG "lmx2572"
#define _LMX2572_DELAY_MS(x)                                  \
    if (osKernelGetState() == osKernelRunning)                \
    {                                                         \
        osDelay(x); /* 延时函数, HAL_Delay(x) / osDelay(x) */ \
    }                                                         \
    else                                                      \
    {                                                         \
        HAL_Delay(x);                                         \
    }

#define REG_TX_NUM 65 // 需要写入LMX2572的寄存器的数目

const uint16_t vcox[6][6] =
    {
        // fMin  fMax  CMin  CMax  AMin  AMax
        {3200, 3650, 131, 19, 138, 137}, // VCO1
        {3650, 4200, 143, 25, 162, 142}, // VCO2
        {4200, 4650, 135, 34, 126, 114}, // VCO3
        {4650, 5200, 136, 25, 195, 172}, // VCO4
        {5200, 5750, 133, 20, 190, 163}, // VCO5
        {5750, 6400, 151, 27, 256, 204}  // VCO6
};

// static lmx2572_dev_t lmx2572_device;

lmx2572_handle_t lmx2572_create(SPI_HandleTypeDef *hspi, GPIO_TypeDef *g, uint16_t p)
{
    if (hspi == NULL || g == NULL)
    {
        return NULL;
    }

    // lmx2572_dev_t lmx2572_device;
    lmx2572_dev_t *lmx2572_device = (lmx2572_dev_t *)calloc(1, sizeof(lmx2572_dev_t));

    lmx2572_device->gpio = g;
    lmx2572_device->pin = p;
    lmx2572_device->spi_dev = hspi;

    return (lmx2572_handle_t)lmx2572_device;
}

uint8_t lmx2572_delete(lmx2572_handle_t *)
{
    return 0;
}

uint8_t lmx2572_write_reg(lmx2572_handle_t dev, uint8_t reg, uint16_t reg_value)
{
    uint8_t ret;
    uint8_t _data[3];
    lmx2572_dev_t *p_device = (lmx2572_dev_t *)dev;
    _data[0] = reg;
    _data[1] = reg_value >> 8;
    _data[2] = reg_value & 0xff;
    HAL_GPIO_WritePin(p_device->gpio, p_device->pin, GPIO_PIN_RESET);
    ret = HAL_SPI_Transmit(p_device->spi_dev, _data, 3, 500);
    HAL_GPIO_WritePin(p_device->gpio, p_device->pin, GPIO_PIN_SET);
    return ret;
}

uint8_t lmx2572_read_reg(lmx2572_handle_t dev, uint8_t reg, uint16_t *reg_value)
{
    uint8_t ret;
    uint8_t _data[3];
    uint8_t _data_r[3];
    lmx2572_dev_t *p_device = (lmx2572_dev_t *)dev;
    _data[0] = reg | 0x80;
    HAL_GPIO_WritePin(p_device->gpio, p_device->pin, GPIO_PIN_RESET);
    ret = HAL_SPI_TransmitReceive(p_device->spi_dev, _data, _data_r, 3, 500);
    HAL_GPIO_WritePin(p_device->gpio, p_device->pin, GPIO_PIN_SET);
    *reg_value = (_data_r[1] << 8) + _data_r[2]; // *reg_value = (_data_r[0]<<8) + _data_r[1];
    return ret;
}
static void delay_ns(unsigned int xns)
{
    unsigned int i, j;
    for (i = 0; i < xns; i++)
    {
        for (j = 0; j < 1; j++)
            ;
    }
}
//------------public function-------------------------
uint8_t lmx2572_reg_init(lmx2572_handle_t dev, const lmx2575_reg_value_table_t table[])
{
    uint8_t ret;
    uint8_t i = 0;
    // while(1) //for test
    ret = lmx2572_write_reg(dev, 0, 0x2012); // RESET
    delay_ns(100);
    for (i = 0; i < REG_TX_NUM; i++)
    {
        ret = lmx2572_write_reg(dev, table[i].reg, table[i].value);
        // ESP_LOGI(TAG,"i=%d,reg=0x%02x,value=0x%04x",i,table[i].reg,table[i].value);
        // _LMX2572_DELAY_MS(1);
        delay_ns(100);
    }
    ret = lmx2572_write_reg(dev, 0, 0x201C); // LOCK
    return ret;
}

// 本振0寄存器PowerDown操作
void lmx2572_sleep(lmx2572_handle_t dev, uint8_t ONorOFF)
{
    if (ONorOFF == 0)
    {
        lmx2572_write_reg(dev, 0, 0x201D); // LOCK  PowerDown
                                           //        TIM_US_Delay(100);
        // _LMX2572_DELAY_MS(1);
        delay_ns(100);
    }
    else if (ONorOFF == 1)
    {
        lmx2572_write_reg(dev, 0, 0x201C); // LOCK  Normal
                                           //        TIM_US_Delay(100);
        // _LMX2572_DELAY_MS(1);
        delay_ns(100);
    }
}

// 本振0寄存器PowerDown操作
void lmx2572_sleep_44(lmx2572_handle_t dev, uint8_t ONorOFF, lmx2572_sleep_sub_e type)
{

    switch (type)
    {
    case LMX2572_SLEEP_ALL_OFF:
        /* 全关 */
        lmx2572_write_reg(dev, 44, 0x14e2);
        break;
    case LMX2572_SLEEP_ALL_2:
        /* 2阶 */
        lmx2572_write_reg(dev, 44, 0x14a2);
        break;
    case LMX2572_SLEEP_ALL_3:
        /* 3阶 */
        lmx2572_write_reg(dev, 44, 0x1462);
        break;
    case LMX2572_SLEEP_ALL_ON:
        /* 全开=2+3阶 */
        lmx2572_write_reg(dev, 44, 0x1422);
        break;

    default:
        lmx2572_write_reg(dev, 44, 0x14e2); /* 全关 */
        break;
    }
}

uint8_t lmx2572_check_self(lmx2572_handle_t dev)
{
    uint8_t ret = 0;
    uint16_t data = 0;
    delay_ns(100);
    ret = lmx2572_read_reg(dev, 0, &data);
    if (ret)
        log_e("lmx2572_read_reg : %#x", data);

    /* read reg0 bit4 and bit1 status, bit4 must = 1, bit1 must = 0 */
    if ((data & 0x12) == 0x10)
    {
        ret = 0;
    }
    else
    {
        ret = 0xFF;
    }

    return ret;
}
